﻿import My3D.BitmapMaterial;
import My3D.Point3D;
import My3D.Screen;
import My3D.TestureInfo;
import My3D.UVPoint;
dynamic class My3D.Face extends Point3D{
	private static var faceIndex:Number = 0;
	/**
	 * the face has been changed of Points or testure, need to be updata to testure
	 * Updataed(face:Face)
	 */
	public static var Updataed:Function;
	/**
	 * create an new faceindex;
	 */
	public static function get NewFaceIndex():Number {
		return faceIndex++;
	}
	//--------------------------------------------------------------------------------------
	//																					private
	public var $testureInfo:TestureInfo;
	public var $rootmc:MovieClip;
	public var $screen:Screen;
	public var $pointA:Point3D;
	public var $pointB:Point3D;
	public var $pointC:Point3D;
	public var visible:Boolean = true;
	
	//--------------------------------------------------------------------------------------
	//																					public
	public function get TestureInfo():TestureInfo {
		return this.$testureInfo;
	}
	public function get RootMc():MovieClip {
		return this.$rootmc;
	}
	public function get Screen():Screen {
		return this.$screen;
	}
	public function set Screen(value:Screen) {
		this.$screen = value;
	}
	
	public function get PointA():Point3D {
		return this.$pointA;
	}
	public function get PointB():Point3D {
		return this.$pointB;
	}
	public function get PointC():Point3D {
		return this.$pointC;
	}
	
	public function set PointA(value:Point3D) {
		if(value!=undefined){
			this.$pointA = value;
			Updataed(this);
		}
	}
	public function set PointB(value:Point3D) {
		if(value!=undefined){
			this.$pointB = value;
			Updataed(this);
		}
	}
	
	public function set PointC(value:Point3D) {
		if(value!=undefined){
			this.$pointC = value;
			Updataed(this);
		}
	}
	public function get ID():String {
		return _say.Name;
	}
	public function getZ():Number {
		return this.$pointA.z + this.$pointB.z + this.$pointC.z / 3;
	}
	//--------------------------------------------------------------------------------------
	//																					function 
	
	public function Face(rootmc:MovieClip) {
		initsay();
		if (rootmc == undefined) {
			_say.wsay("not set face's root mc.");
		}
		this.$rootmc = rootmc;
		initvars();
		_say.msay("inited!");
	}
	private function initvars() {
		this.$testureInfo = new My3D.TestureInfo();
		this.$pointA = new Point3D();
		this.$pointB = new Point3D();
		this.$pointC = new Point3D();
	}
	public function setTestureMaterial(tm:BitmapMaterial) {
		this.$testureInfo.bitmapMaterial = tm;
		Updataed(this);
	}
	public function setTestureColors(backGroundColor:Number, backGroundAlpha:Number, lineThickness:Number, lineColor:Number, lineAlpha:Number) {
		this.$testureInfo.backGroundColor = backGroundColor;
		this.$testureInfo.backGroundAlpha = backGroundAlpha;
		this.$testureInfo.lineThickness = lineThickness;
		this.$testureInfo.lineColor = lineColor;
		this.$testureInfo.lineAlpha = lineAlpha;
		Updataed(this);
	}
	
	public function AddPoints(pointarr:Array, UVPointA:UVPoint, UVPointB:UVPoint, UVPointC:UVPoint):Boolean {
		if (UVPointA == undefined) {
			UVPointA = new UVPoint(0, 100);
		}
		if (UVPointB == undefined) {
			UVPointB = new UVPoint(0, 0);
		}
		if (UVPointC == undefined) {
			UVPointC = new UVPoint(100, 0);
		}
		if (pointarr.length >= 3) {
			for (var i = 0; i < pointarr.length; i++) {
				var p:Point3D = Point3D(pointarr[i]);
				if (p == null) {
					_say.esay("Point error![" + pointarr[i] + "]")
					return false;
				}
			}
			this.$pointA = Point3D(pointarr[0]);
			this.$pointB = Point3D(pointarr[1]);
			this.$pointC = Point3D(pointarr[2]);
			
			var w:Number = 0;
			var h:Number = 0;
			this.$testureInfo.UVPointOffset = 0;
			this.$testureInfo.UVpointA = UVPointA;
			this.$testureInfo.UVpointB = UVPointB;
			this.$testureInfo.UVpointC = UVPointC;
			
			w = UVPointC.U - UVPointB.U;
			h = UVPointB.V - UVPointA.V;
			
			if (w == 0 || h == 0) {
				w = UVPointA.U - UVPointC.U;
				h = UVPointC.V - UVPointB.V;
				if (w == 0 || h == 0) {
					w = UVPointB.U - UVPointA.U;
					h = UVPointA.V - UVPointC.V;
					if (w == 0 || h == 0) {
					}else {
						this.$testureInfo.UVPointOffset = 2;
					}
				}else {
					this.$testureInfo.UVPointOffset = 1;
				}
			}
			
			Updataed(this);
			return true;
		}else {
			_say.esay("face points should more then 3![" + pointarr + "]")
			return false;
		}
	}
	public function clone(facemc:MovieClip):Face {
		var nf:Face = new Face(facemc);
		nf.$screen = this.$screen;
		TestureInfo.copy(this.$testureInfo, nf.$testureInfo);
		nf.PointA = this.$pointA.clone();
		nf.PointB = this.$pointB.clone();
		nf.PointC = this.$pointC.clone();
		return nf;
	}
	
	public function dispose() {
		if (this.$screen != undefined) {
			//dispose in screen face array
		}
	}
	public function toString() {
		return "(" + this.ID + ",z:" + this.Z+")";
	}
	////////////////////////////////////////////////////////////////      output
	private var _say:Say;
	private function initsay() {
		_say = new Say("Face"+Face.NewFaceIndex);
		_say.addListener(this);
		this[Say.M_SAY] = this.sayfun;
	}
	private function sayfun(o) {
		trace(o);
	}
}